home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / GAMES / C014.ZIP / LARN_SRC.ZIP / SAVELEV.C < prev    next >
C/C++ Source or Header  |  1993-11-17  |  4KB  |  178 lines

  1. /* savelev.c */
  2. #include "header.h"
  3. #include "larndefs.h"
  4.  
  5. # ifdef MSDOS
  6.  
  7. extern int swapfd;      /* swap file file descriptor */
  8.  
  9. DISKBLOCK *
  10. getfreediskblk()
  11. {
  12.     DISKBLOCK   *dp;
  13.  
  14.     for (dp = diskblks; dp; dp = dp->next)
  15.         if (dp->level == FREEBLOCK)
  16.             return dp;
  17.     levelinfo();
  18.     error("Can't find a free disk block ?\n");
  19. }
  20.  
  21. RAMBLOCK *
  22. getramblk(lev)
  23. {
  24.     RAMBLOCK    *rp, *orp;
  25.     DISKBLOCK   *dp;
  26.     long        otime;
  27.     unsigned int    bytes;
  28.  
  29.     /* Check if the level is in memory already.
  30.      */
  31.     for (rp = ramblks; rp; rp = rp->next)
  32.         if (rp->level == lev)
  33.             return rp;
  34.  
  35.     /* Else grab the first available one.
  36.      */
  37.     for (rp = ramblks; rp; rp = rp->next)
  38.         if (rp->level == FREEBLOCK)
  39.             return rp;
  40.  
  41.     /* No ramblocks free, so swap out the oldest level
  42.      */
  43.     dp = getfreediskblk();
  44.  
  45. # ifdef ndef
  46. warn("\nTrying to swap\n");
  47. # endif
  48.  
  49.     /* Find the oldest level for swapping out.
  50.      */
  51.     otime = ramblks->gtime;
  52.     orp = ramblks;
  53.     for (rp = ramblks->next; rp; rp = rp->next) {
  54.         if (rp->gtime < otime) {
  55.             otime = rp->gtime;
  56.             orp = rp;
  57.         }
  58.     }
  59.  
  60.     /* Send the oldest level out to disk.
  61.      */
  62.     if (lseek(swapfd, dp->fpos, 0) < 0)
  63.         error("Can't seek to %ld\n", dp->fpos);
  64.  
  65.     bytes = sizeof rp->cell;
  66.     if (write(swapfd, (char *) orp->cell, bytes) != bytes)
  67.         error("Out of space writing swap file !\n");
  68.  
  69.     /* Update the level information
  70.      */
  71.     dp->level = orp->level;
  72.     dp->gtime = orp->gtime;
  73.     orp->level = FREEBLOCK;
  74. # ifdef ndef
  75. warn("Successful swap\n");
  76. # endif
  77.     return orp;
  78. }
  79.  
  80.  
  81. # endif
  82.  
  83. /*
  84.  *  routine to save the present level into storage
  85.  */
  86. savelevel()
  87.     {
  88.     register struct cel *pcel;
  89.     register char *pitem,*pknow,*pmitem;
  90.     register short *phitp,*piarg;
  91.     register struct cel *pecel;
  92.  
  93. # ifdef MSDOS
  94.     RAMBLOCK    *rp;
  95.  
  96.     rp = getramblk(level);
  97.     pcel = rp->cell;
  98.     rp->gtime = gtime;
  99.     rp->level = level;
  100. # else
  101.     pcel = &cell[level*MAXX*MAXY];  /* pointer to this level's cells */
  102. # endif
  103.     pecel = pcel + MAXX*MAXY;   /* pointer to past end of this level's cells */
  104.     pitem=item[0]; piarg=iarg[0]; pknow=know[0]; pmitem=mitem[0]; phitp=hitp[0];
  105.     while (pcel < pecel)
  106.         {
  107.         pcel->mitem  = *pmitem++;
  108.         pcel->hitp   = *phitp++;
  109.         pcel->item   = *pitem++;
  110.         pcel->know   = *pknow++;
  111.         pcel->iarg   = *piarg++;
  112.         pcel++;
  113.         }
  114.     }
  115.  
  116.  
  117. /*
  118.  *  routine to restore a level from storage
  119.  */
  120. getlevel()
  121.     {
  122.     register struct cel *pcel;
  123.     register char *pitem,*pknow,*pmitem;
  124.     register short *phitp,*piarg;
  125.     register struct cel *pecel;
  126.  
  127. # ifdef MSDOS
  128.     RAMBLOCK    *rp;
  129.     DISKBLOCK   *dp;
  130.     unsigned int    bytes;
  131.  
  132.     /* Is the level in memory already ?
  133.      */
  134.     for (rp = ramblks; rp; rp = rp->next)
  135.         if (rp->level == level)
  136.             goto haverp;
  137.  
  138.     /* Is it on disk ?
  139.      */
  140.     for (dp = diskblks; dp; dp = dp->next)
  141.         if (dp->level == level)
  142.             break;
  143.     if (dp == NULL) {
  144.         levelinfo();
  145.         error("Level %d is neither in memory nor on disk\n", level);
  146.     }
  147.  
  148.     /* Make room for it and read it in.
  149.      */
  150.     rp = getramblk(level);
  151.     if (lseek(swapfd, dp->fpos, 0) < 0)
  152.         error("Can't seek to %ld\n", dp->fpos);
  153.     bytes = sizeof rp->cell;
  154.     if (read(swapfd, (char *) rp->cell, bytes) != bytes)
  155.         error("Didn't read %u bytes\n", bytes);
  156.  
  157.     /* The disk space is available for future swaps.
  158.      */
  159.     dp->level = FREEBLOCK;
  160. haverp:
  161.     pcel = rp->cell;
  162.     rp->level = FREEBLOCK;
  163. # else
  164.     pcel = &cell[level*MAXX*MAXY];  /* pointer to this level's cells */
  165. # endif
  166.     pecel = pcel + MAXX*MAXY;   /* pointer to past end of this level's cells */
  167.     pitem=item[0]; piarg=iarg[0]; pknow=know[0]; pmitem=mitem[0]; phitp=hitp[0];
  168.     while (pcel < pecel)
  169.         {
  170.         *pmitem++ = pcel->mitem;
  171.         *phitp++ = pcel->hitp;
  172.         *pitem++ = pcel->item;
  173.         *pknow++ = pcel->know;
  174.         *piarg++ = pcel->iarg;
  175.         pcel++;
  176.         }
  177.     }
  178.